package yu.com.time.calclator

import yu.com.time.toLocalDateTime
import yu.com.time.toTimestamp
import yu.com.time.unit.DateTimeUnit
import yu.com.time.unit.DateTimeUnit.*
import java.sql.Timestamp
import java.time.LocalDateTime
import java.time.temporal.ChronoUnit
import java.util.*


/**
 * Timestamp时间戳计算器
 * created zpf on 2018/10/23 0023
 * @param origTime 原始时间
 * @param unit     时间计算单位
 */
open class TimestampCalculator(val origTime: java.util.Date, val unit: DateTimeUnit) : Calculator<TimestampCalculator, Date>, Timestamp(origTime.time) {

    /**jdk8本地日期时间*/
    private val localDateTime: LocalDateTime = origTime.toLocalDateTime()

    override fun plus(addition: Long): TimestampCalculator {
        val time = when (unit) {
            YEAR -> localDateTime.plusYears(addition).toTimestamp()
            MONTH -> localDateTime.plusMonths(addition).toTimestamp()
            WEEK -> localDateTime.plusWeeks(addition).toTimestamp()
            DAY -> localDateTime.plusDays(addition).toTimestamp()
            HOUR -> localDateTime.plusHours(addition).toTimestamp()
            MINUTE -> localDateTime.plusMinutes(addition).toTimestamp()
            SECOND -> localDateTime.plusSeconds(addition).toTimestamp()
            MILLI -> Timestamp(origTime.time + addition)
            NANO -> localDateTime.plusNanos(addition).toTimestamp()
        }
        return TimestampCalculator(time, unit)
    }

    override fun minus(subtraction: Date): Long {
        val refer = subtraction.toLocalDateTime()
        return when (unit) {
            YEAR -> refer.until(localDateTime, ChronoUnit.YEARS)
            MONTH -> refer.until(localDateTime, ChronoUnit.MONTHS)
            WEEK -> refer.until(localDateTime, ChronoUnit.WEEKS)
            DAY -> refer.until(localDateTime, ChronoUnit.DAYS)
            HOUR -> refer.until(localDateTime, ChronoUnit.HOURS)
            MINUTE -> refer.until(localDateTime, ChronoUnit.MINUTES)
            SECOND -> refer.until(localDateTime, ChronoUnit.SECONDS)
            MILLI -> refer.until(localDateTime, ChronoUnit.MILLIS)
            NANO -> refer.until(localDateTime, ChronoUnit.NANOS)
        }
    }
}